package com.sky.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.util.UriUtils;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.net.URL;
@Data
@AllArgsConstructor
@Slf4j
public class BaiduUtil {


    private String ak;
    private String url;
    private String address;
    /**
     * 路径判断
     */
    /**
     * 默认ak
     * 选择了ak，使用IP白名单校验：
     * 根据您选择的AK已为您生成调用代码
     * 检测到您当前的ak设置了IP白名单校验
     * 您的IP白名单中的IP非公网IP，请设置为公网IP，否则将请求失败
     * 请在IP地址为xxxxxxx的计算发起请求，否则将请求失败
     */
    public double locationJudge(String userLocation) {
        Map admin = null;
        Map user= null;
        try {
            admin = this.requestGetAK(this.address);
            user = this.requestGetAK(userLocation);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // 将 BigDecimal 转换为 double
        double adminLat = ((BigDecimal) admin.get("lat")).doubleValue();
        double adminLng = ((BigDecimal) admin.get("lng")).doubleValue();
        double userLat = ((BigDecimal) user.get("lat")).doubleValue();
        double userLng = ((BigDecimal) user.get("lng")).doubleValue();

        return calculateSimpleDistance(adminLat, adminLng, userLat, userLng);

    }
    private static double toRadians(double degree) {
        return degree * Math.PI / 180.0;
    }
    public static double calculateSimpleDistance(double lat1, double lon1, double lat2, double lon2) {
        double dLat = toRadians(lat2 - lat1);
        double dLon = toRadians(lon2 - lon1);
        // 使用简化的直线距离公式
        double distance = Math.sqrt(dLat * dLat + dLon * dLon) * 60 * 1.852;
        return distance;
    }
    public Map  requestGetAK(String address) throws Exception {
        String strUrl=this.url;
        Map<String, String> param = new LinkedHashMap<String, String>();
        param.put("address", address);
        param.put("output", "json");
        param.put("ak", this.ak);
        param.put("callback", "showLocation");
        if (strUrl == null || strUrl.length() <= 0 || param == null || param.size() <= 0) {
            return null;
        }

        StringBuffer queryString = new StringBuffer();
        queryString.append(strUrl);
        for (Map.Entry<?, ?> pair : param.entrySet()) {
            queryString.append(pair.getKey() + "=");
            //    第一种方式使用的 jdk 自带的转码方式  第二种方式使用的 spring 的转码方法 两种均可
            //    queryString.append(URLEncoder.encode((String) pair.getValue(), "UTF-8").replace("+", "%20") + "&");
            queryString.append(UriUtils.encode((String) pair.getValue(), "UTF-8") + "&");
        }

        if (queryString.length() > 0) {
            queryString.deleteCharAt(queryString.length() - 1);
        }

        java.net.URL url = new URL(queryString.toString());
        System.out.println(queryString.toString());
        URLConnection httpConnection = (HttpURLConnection) url.openConnection();
        httpConnection.connect();

        InputStreamReader isr = new InputStreamReader(httpConnection.getInputStream());
        BufferedReader reader = new BufferedReader(isr);
        StringBuffer buffer = new StringBuffer();
        String line;
        while ((line = reader.readLine()) != null) {
            buffer.append(line);
        }
        reader.close();
        isr.close();
        System.out.println("AK: " + buffer.toString());
        String res = buffer.toString();
        String jsonPart = res.substring(res.indexOf("{"), res.lastIndexOf("}") + 1);
        JSONObject json =  JSON.parseObject(jsonPart);
        Map map=new HashMap<>();
        map.put("lng", json.getJSONObject("result").getJSONObject("location").get("lng"));
        map.put("lat", json.getJSONObject("result").getJSONObject("location").get("lat"));
        return map;
    }
}
